package com.simplegui.swing;

import java.io.File;
import java.net.URL;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

import com.simplegui.api.Sound;

public class SoundSwingImpl implements Runnable, Sound{

	private static final int BUFFER_SIZE = 2200;

	private AudioInputStream audioStream;
	private SourceDataLine sourceLine;
	private File soundFile;
	int nBytesRead;

	private boolean playing;
	private boolean alive;
	private boolean loop;


	public SoundSwingImpl(String fileName) {
		try {
        	this.playing = false;
			this.alive = true;
			this.loop = false;
			this.nBytesRead = 0;
			
			URL url = ClassLoader.getSystemResource(fileName);
        	this.soundFile = new File(url.toURI());
        	AudioSystem.getAudioFileFormat(soundFile);
        	this.audioStream = AudioSystem.getAudioInputStream(soundFile);			

			AudioFormat audioFormat = audioStream.getFormat();
			DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);

			sourceLine = (SourceDataLine) AudioSystem.getLine(info);
			sourceLine.open(audioFormat);

			sourceLine.start();
			new Thread(this).start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void play(){
		playing = true;
	}

	public void pause() {
		playing = false;
	}
	
	public void rewind(){
		try {
			AudioSystem.getAudioFileFormat(soundFile);
        	this.audioStream = AudioSystem.getAudioInputStream(soundFile);
        	this.nBytesRead = 0;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void stop(){
		alive = false;
	}

	@Override
	public void run() {
		try {
			while (alive){
				if (playing){
					sourceLine.flush();
					byte[] abData = new byte[BUFFER_SIZE];
					while (alive && playing && nBytesRead != -1) {
						nBytesRead = audioStream.read(abData, 0, abData.length);
						if (nBytesRead >= 0) {
							sourceLine.write(abData, 0, nBytesRead);
						}
					}
					if (nBytesRead == -1){
						if (loop){
							rewind();
						}else{
							pause();
						}
					}
				}
				Thread.sleep(100);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void setLoop(boolean loop) {
		this.loop = loop;
	}

	@Override
	public void setVolume(double volume) {
	}
}